package com.rbmh.network.utils;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.extractor.WordExtractor;
import org.apache.poi.hwpf.usermodel.Range;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units;

import java.io.*;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class WordDocumentHandler {

    /**
     * 判断文件是 .doc 还是 .docx 格式
     * @param filePath 文件路径
     * @return true 如果是 .docx 格式，false 如果是 .doc 格式
     */
    private static boolean isDocxFormat(String filePath) {
        return filePath.toLowerCase().endsWith(".docx");
    }

    /**
     * 读取 Word 文档内容（支持 .doc 和 .docx）
     * @param filePath Word 文档路径
     * @return 文档内容字符串
     */
    public static String readWordDocument(String filePath) {
        StringBuilder content = new StringBuilder();

        try {
            if (isDocxFormat(filePath)) {
                // 处理 .docx 格式
                try (FileInputStream fis = new FileInputStream(filePath);
                     XWPFDocument document = new XWPFDocument(fis)) {

                    // 读取段落
                    List<XWPFParagraph> paragraphs = document.getParagraphs();
                    for (XWPFParagraph para : paragraphs) {
                        content.append(para.getText()).append("\n");
                    }

                    // 读取表格
                    List<XWPFTable> tables = document.getTables();
                    for (XWPFTable table : tables) {
                        for (XWPFTableRow row : table.getRows()) {
                            for (XWPFTableCell cell : row.getTableCells()) {
                                content.append(cell.getText()).append("\t");
                            }
                            content.append("\n");
                        }
                    }
                }
            } else {
                // 处理 .doc 格式
                try (FileInputStream fis = new FileInputStream(filePath);
                     HWPFDocument document = new HWPFDocument(fis);
                     WordExtractor extractor = new WordExtractor(document)) {

                    content.append(extractor.getText());
                }
            }

        } catch (IOException e) {
            System.err.println("读取文档时出错: " + e.getMessage());
            e.printStackTrace();
        }

        return content.toString();
    }

    /**
     * 创建新的 Word 文档（默认创建 .docx 格式）
     * @param filePath 保存路径
     * @param content 要写入的内容
     */
    public static void createWordDocument(String filePath, String content) {
        // 确保文件扩展名是 .docx
        if (!filePath.toLowerCase().endsWith(".docx")) {
            filePath = filePath + ".docx";
        }

        try (XWPFDocument document = new XWPFDocument();
             FileOutputStream out = new FileOutputStream(filePath)) {

            // 创建段落并添加内容
            XWPFParagraph paragraph = document.createParagraph();
            XWPFRun run = paragraph.createRun();
            run.setText(content);

            document.write(out);
            System.out.println("文档创建成功: " + filePath);

        } catch (IOException e) {
            System.err.println("创建文档时出错: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 修改现有 Word 文档（支持 .doc 和 .docx）
     * @param filePath 文档路径
     * @param findText 要查找的文本
     * @param replaceText 替换文本
     */
    public static void modifyWordDocument(String filePath, String findText, String replaceText) {
        try {
            if (isDocxFormat(filePath)) {
                modifyDocxDocument(filePath, findText, replaceText);
            } else {
                modifyDocDocument(filePath, findText, replaceText);
            }
        } catch (IOException e) {
            System.err.println("修改文档时出错: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 修改 .docx 文档
     */
    private static void modifyDocxDocument(String filePath, String findText, String replaceText) throws IOException {
        try (FileInputStream fis = new FileInputStream(filePath);
             XWPFDocument document = new XWPFDocument(fis)) {

            boolean modified = false;

            // 在段落中查找并替换文本
            for (XWPFParagraph para : document.getParagraphs()) {
                String text = para.getText();
                if (text.contains(findText)) {
                    // 清除原有内容
                    for (int i = para.getRuns().size() - 1; i >= 0; i--) {
                        para.removeRun(i);
                    }
                    // 添加新内容
                    XWPFRun run = para.createRun();
                    run.setText(text.replace(findText, replaceText));
                    modified = true;
                }
            }

            // 在表格中查找并替换文本
            for (XWPFTable table : document.getTables()) {
                for (XWPFTableRow row : table.getRows()) {
                    for (XWPFTableCell cell : row.getTableCells()) {
                        for (XWPFParagraph para : cell.getParagraphs()) {
                            String text = para.getText();
                            if (text.contains(findText)) {
                                // 清除原有内容
                                for (int i = para.getRuns().size() - 1; i >= 0; i--) {
                                    para.removeRun(i);
                                }
                                // 添加新内容
                                XWPFRun run = para.createRun();
                                run.setText(text.replace(findText, replaceText));
                                modified = true;
                            }
                        }
                    }
                }
            }

            if (modified) {
                // 保存修改后的文档
                try (FileOutputStream out = new FileOutputStream(filePath)) {
                    document.write(out);
                    System.out.println("文档修改成功: " + filePath);
                }
            } else {
                System.out.println("未找到要替换的文本: " + findText);
            }
        }
    }

    /**
     * 修改 .doc 文档（.doc 格式的修改比较复杂，这里提供基本实现）
     */
    private static void modifyDocDocument(String filePath, String findText, String replaceText) throws IOException {
        System.out.println("警告：.doc 格式的文档修改功能有限，建议转换为 .docx 格式进行完整操作");

        // 读取内容
        String content;
        try (FileInputStream fis = new FileInputStream(filePath);
             HWPFDocument document = new HWPFDocument(fis);
             WordExtractor extractor = new WordExtractor(document)) {

            content = extractor.getText().replace(findText, replaceText);
        }

        // 创建新的 .docx 文档（因为 .doc 修改比较复杂）
        String newFilePath = filePath.replace(".doc", ".docx");
        createWordDocument(newFilePath, content);
        System.out.println("已创建新的 .docx 文档: " + newFilePath);
    }

    /**
     * 向文档添加图片（仅支持 .docx）
     * @param filePath 文档路径
     * @param imagePath 图片路径
     */
    public static void addImageToDocument(String filePath, String imagePath) {
        if (!isDocxFormat(filePath)) {
            System.err.println("添加图片功能仅支持 .docx 格式");
            return;
        }

        try (FileInputStream fis = new FileInputStream(filePath);
             XWPFDocument document = new XWPFDocument(fis);
             FileInputStream imageStream = new FileInputStream(imagePath)) {

            // 创建新段落并添加图片
            XWPFParagraph paragraph = document.createParagraph();
            XWPFRun run = paragraph.createRun();

            // 确定图片类型
            int pictureType;
            if (imagePath.toLowerCase().endsWith(".png")) {
                pictureType = XWPFDocument.PICTURE_TYPE_PNG;
            } else if (imagePath.toLowerCase().endsWith(".gif")) {
                pictureType = XWPFDocument.PICTURE_TYPE_GIF;
            } else if (imagePath.toLowerCase().endsWith(".bmp")) {
                pictureType = XWPFDocument.PICTURE_TYPE_BMP;
            } else {
                pictureType = XWPFDocument.PICTURE_TYPE_JPEG; // 默认 JPEG
            }

            run.addPicture(imageStream, pictureType, imagePath, Units.toEMU(200), Units.toEMU(200));

            // 保存文档
            try (FileOutputStream out = new FileOutputStream(filePath)) {
                document.write(out);
                System.out.println("图片添加成功: " + filePath);
            }

        } catch (IOException | InvalidFormatException e) {
            System.err.println("添加图片时出错: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 获取文档信息
     * @param filePath 文档路径
     */
    public static void getDocumentInfo(String filePath) {
        try {
            if (isDocxFormat(filePath)) {
                try (FileInputStream fis = new FileInputStream(filePath);
                     XWPFDocument document = new XWPFDocument(fis)) {

                    System.out.println("文档格式: .docx");
                    System.out.println("段落数量: " + document.getParagraphs().size());
                    System.out.println("表格数量: " + document.getTables().size());
                }
            } else {
                try (FileInputStream fis = new FileInputStream(filePath);
                     HWPFDocument document = new HWPFDocument(fis);
                     WordExtractor extractor = new WordExtractor(document)) {

                    System.out.println("文档格式: .doc");
                    System.out.println("字符数量: " + extractor.getText().length());
                    Range range = document.getRange();
                    System.out.println("段落数量: " + range.numParagraphs());
                }
            }
        } catch (IOException e) {
            System.err.println("获取文档信息时出错: " + e.getMessage());
        }
    }

    /**
     * 精确替换文本并保留样式（推荐）
     * @param filePath 文档路径
     * @param findText 要查找的文本
     * @param replaceText 替换文本
     */
    public static void replaceTextWithStyle(String filePath, String findText, String replaceText) {
        try (FileInputStream fis = new FileInputStream(filePath);
             XWPFDocument document = new XWPFDocument(fis)) {

            boolean modified = false;

            // 在段落中查找并替换
            for (XWPFParagraph para : document.getParagraphs()) {
                if (replaceInParagraph(para, findText, replaceText)) {
                    modified = true;
                }
            }

            // 在表格中查找并替换
            for (XWPFTable table : document.getTables()) {
                for (XWPFTableRow row : table.getRows()) {
                    for (XWPFTableCell cell : row.getTableCells()) {
                        for (XWPFParagraph para : cell.getParagraphs()) {
                            if (replaceInParagraph(para, findText, replaceText)) {
                                modified = true;
                            }
                        }
                    }
                }
            }

            if (modified) {
                try (FileOutputStream out = new FileOutputStream(filePath)) {
                    document.write(out);
                    System.out.println("替换成功，样式已保留！");
                }
            } else {
                System.out.println("未找到要替换的文本: " + findText);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 在单个段落中替换文本并保留样式
     */
    private static boolean replaceInParagraph(XWPFParagraph para, String findText, String replaceText) {
        boolean modified = false;
        List<XWPFRun> runs = para.getRuns();

        // 先检查整个段落是否包含目标文本
        String paragraphText = para.getText();
        if (!paragraphText.contains(findText)) {
            return false;
        }

        // 构建所有运行的文本内容
        StringBuilder combinedText = new StringBuilder();
        for (XWPFRun run : runs) {
            String runText = run.getText(0);
            if (runText != null) {
                combinedText.append(runText);
            }
        }

        String fullText = combinedText.toString();
        if (fullText.contains(findText)) {
            System.out.println("找到文本: " + findText + " 在段落中");

            // 清空所有运行的文本
            for (XWPFRun run : runs) {
                run.setText("", 0);
            }

            // 重新构建文本，只替换目标部分
            String newText = fullText.replace(findText, replaceText);

            // 使用第一个运行的样式来设置新文本
            if (!runs.isEmpty()) {
                XWPFRun firstRun = runs.get(0);
                firstRun.setText(newText, 0);
                modified = true;
            } else {
                // 如果没有运行，创建新的运行
                XWPFRun newRun = para.createRun();
                newRun.setText(newText);
                modified = true;
            }
        }

        return modified;
    }

    /**
     * 更精确的样式保留方法（针对数字替换优化）
     * @param filePath 文档路径
     */
    public static void replacePersonnelNumberWithStyle(String filePath) {
        try (FileInputStream fis = new FileInputStream(filePath);
             XWPFDocument document = new XWPFDocument(fis)) {

            Pattern pattern = Pattern.compile("新干人事调干字（2025）第(\\d{3})号");
            boolean modified = false;

            // 处理段落
            for (XWPFParagraph para : document.getParagraphs()) {
                if (replaceNumberInParagraph(para, pattern)) {
                    modified = true;
                }
            }

            // 处理表格
            for (XWPFTable table : document.getTables()) {
                for (XWPFTableRow row : table.getRows()) {
                    for (XWPFTableCell cell : row.getTableCells()) {
                        for (XWPFParagraph para : cell.getParagraphs()) {
                            if (replaceNumberInParagraph(para, pattern)) {
                                modified = true;
                            }
                        }
                    }
                }
            }

            if (modified) {
                try (FileOutputStream out = new FileOutputStream(filePath)) {
                    document.write(out);
                    System.out.println("人事调干字号已成功递增并保留样式！");
                }
            } else {
                System.out.println("未找到人事调干字号");
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 在段落中替换数字并保留样式
     */
    private static boolean replaceNumberInParagraph(XWPFParagraph para, Pattern pattern) {
        String paragraphText = para.getText();
        Matcher matcher = pattern.matcher(paragraphText);

        if (matcher.find()) {
            String oldNumber = matcher.group(1);
            int newNumber = Integer.parseInt(oldNumber) + 1;
            String newNumberStr = String.format("%03d", newNumber);

            System.out.println("找到号码: " + oldNumber + " -> 将改为: " + newNumberStr);

            // 保留原有样式，只替换数字部分
            List<XWPFRun> runs = para.getRuns();
            StringBuilder currentText = new StringBuilder();

            // 先收集所有文本
            for (XWPFRun run : runs) {
                String runText = run.getText(0);
                if (runText != null) {
                    currentText.append(runText);
                }
            }

            String fullText = currentText.toString();
            String newText = fullText.replace(
                    "新干人事调干字（2025）第" + oldNumber + "号",
                    "新干人事调干字（2025）第" + newNumberStr + "号"
            );

            // 清空原有运行
            for (XWPFRun run : runs) {
                run.setText("", 0);
            }

            // 使用第一个运行的样式重新设置文本
            if (!runs.isEmpty()) {
                runs.get(0).setText(newText, 0);
            } else {
                para.createRun().setText(newText);
            }

            return true;
        }

        return false;
    }

    /**
     * 高级方法：逐个运行处理，最大限度保留样式
     * @param filePath 文档路径
     */
    public static void advancedReplaceWithStyle(String filePath) {
        try (FileInputStream fis = new FileInputStream(filePath);
             XWPFDocument document = new XWPFDocument(fis)) {

            boolean modified = false;
            String targetPattern = "080";
            String replacement = "081";

            // 处理段落
            for (XWPFParagraph para : document.getParagraphs()) {
                if (advancedReplaceInParagraph(para, targetPattern, replacement)) {
                    modified = true;
                }
            }

            // 处理表格
            for (XWPFTable table : document.getTables()) {
                for (XWPFTableRow row : table.getRows()) {
                    for (XWPFTableCell cell : row.getTableCells()) {
                        for (XWPFParagraph para : cell.getParagraphs()) {
                            if (advancedReplaceInParagraph(para, targetPattern, replacement)) {
                                modified = true;
                            }
                        }
                    }
                }
            }

            if (modified) {
                try (FileOutputStream out = new FileOutputStream(filePath)) {
                    document.write(out);
                    System.out.println("高级替换完成，样式完美保留！");
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 高级段落替换方法
     */
    private static boolean advancedReplaceInParagraph(XWPFParagraph para, String find, String replace) {
        List<XWPFRun> runs = para.getRuns();
        boolean modified = false;

        for (XWPFRun run : runs) {
            String runText = run.getText(0);
            if (runText != null && runText.contains(find)) {
                String newText = runText.replace(find, replace);
                run.setText(newText, 0);
                modified = true;
                System.out.println("在运行中替换: " + find + " -> " + replace);
            }
        }

        return modified;
    }


}